package com.kapcb.common.result;

import cn.hutool.core.date.DatePattern;
import com.kapcb.common.enums.ResultCodeEnum;
import com.kapcb.common.exception.FrameworkException;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Objects;

/**
 * <a>Title: ResultMessage </a>
 * <a>Author: cb <a>
 * <a>Description: ResultMessage <a>
 *
 * @author cb
 * @version 1.0
 * @date 2024/4/19 17:01
 * @since 1.0
 */
@Getter
@Setter
@ToString
public class ResultMessage<T> implements Result, Serializable {

    private static final long serialVersionUID = -3394223841710063173L;

    /**
     * 状态码
     */
    private final Integer code;

    /**
     * 消息
     */
    private final String message;

    /**
     * 返回数据
     */
    private final T data;

    /**
     * 请求链路 id
     */
    private String traceId;

    /**
     * 时间戳
     */
    private String currentTime;

    public ResultMessage(Integer code, String message) {
        this.code = code;
        this.message = message;
        this.data = null;
        this.traceId = "";
        this.currentTime = getCurrentTime();
    }

    public ResultMessage(ResultCodeEnum resultCodeEnum, T data) {
        this.code = resultCodeEnum.code();
        this.message = resultCodeEnum.message();
        this.data = data;
        this.traceId = "";
        this.currentTime = getCurrentTime();
    }

    private static String getCurrentTime() {
        return DatePattern.NORM_DATETIME_MS_FORMATTER.format(LocalDateTime.now());
    }

    /**
     * 响应成功并返回数据
     *
     * @param data 数据
     * @param <T>  数据类型
     * @return ResultMessage<T>
     */
    public static <T> ResultMessage<T> success(T data) {
        return new ResultMessage<>(ResultCodeEnum.SUCCESS, data);
    }

    /**
     * 响应成功并返回 id
     *
     * @param id Long
     * @return ResultMessage<String>
     */
    public static ResultMessage<String> successWithId(Long id) {
        return new ResultMessage<>(ResultCodeEnum.SUCCESS, String.valueOf(id));
    }

    /**
     * 成功响应并返回空值
     *
     * @param v   空值
     * @param <T> 数据类型
     * @return ResultMessage<T>
     */
    public static <T> ResultMessage<T> successWithNull(Void v) {
        return new ResultMessage<>(ResultCodeEnum.SUCCESS, null);
    }

    /**
     * 失败响应
     *
     * @param resultCode 返回状态
     * @param <T>    数据类型
     * @return ResultMessage<T>
     */
    public static <T> ResultMessage<T> failure(ResultCode resultCode) {
        return failure(resultCode.code(), resultCode.message());
    }

    /**
     * 失败响应
     *
     * @param resultCodeEnum 返回状态枚举
     * @param <T>            数据类型
     * @return ResultMessage<T>
     */
    public static <T> ResultMessage<T> failure(ResultCodeEnum resultCodeEnum) {
        return failure(resultCodeEnum.code(), resultCodeEnum.message());
    }

    /**
     * 失败响应
     *
     * @param code    状态码
     * @param message 消息
     * @param <T>     数据类型
     * @return ResultMessage<T>
     */
    public static <T> ResultMessage<T> failure(Integer code, String message) {
        if (Objects.isNull(code) || StringUtils.isBlank(message)) {
            throw new FrameworkException("失败状态码、失败消息均不能为空! 请选择更友好的状态码与异常提示!");
        }
        if (ResultCodeEnum.SUCCESS.code().equals(code)) {
            throw new FrameworkException("失败状态码不能与成功状态码一致! 请更换更符合业务的异常状态码!");
        }
        return new ResultMessage<>(code, message);
    }
}
